package com.vimi8.ebb;


import com.vimi8.ebb.configuration.BaseJwtAccessTokenConverterImpl;
import com.vimi8.ebb.configuration.CookieTokenExtractor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import springfox.documentation.swagger2.annotations.EnableSwagger2;


@SpringBootApplication
@EnableSwagger2
@EnableResourceServer
public class Swagger2SpringBoot extends ResourceServerConfigurerAdapter {
	@Value("${security.oauth2.resource.jwt.keyValue}")
	private String publicKey;
	@Value("${security.oauth2.resource.id}")
	private String resourceId;

	public static void main(String[] args) throws Exception {

		SpringApplication.run(Swagger2SpringBoot.class, args);
	}

	@Override
	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

		resources.resourceId(resourceId).tokenExtractor(new CookieTokenExtractor());
	}

	@Override
	public void configure(HttpSecurity http) throws Exception {
		//地理信息的权限控制
		http.authorizeRequests().antMatchers(HttpMethod.GET,"/geo/**").permitAll();
		//电商经营主体权限控制
	//	http.authorizeRequests().antMatchers(HttpMethod.POST,"/ebb/**").permitAll();
		//http.authorizeRequests().antMatchers(HttpMethod.GET,"/ebb/**").permitAll();
	//	http.authorizeRequests().antMatchers(HttpMethod.PUT,"/ebb/**").permitAll();
	//	http.authorizeRequests().antMatchers(HttpMethod.DELETE,"/ebb/**").permitAll();
		http.authorizeRequests().antMatchers(HttpMethod.GET,"/front/**").permitAll();
		http.authorizeRequests().antMatchers(HttpMethod.GET,"/train/info/export/").permitAll();
		http.authorizeRequests().antMatchers(HttpMethod.GET,"/train/member/export/").permitAll();


		///sit/sitServerId/
		//anyRequest() authenticated()必须在最后


		((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)http.authorizeRequests().anyRequest()).authenticated();
// /ebb/list/
		//antMatchers(HttpMethod.GET, "**").access("#oauth2.hasScope('read', 'write', 'trust')")//@PreAuthorize("#oauth2.hasScope('read', 'write', 'trust')")

		http
				.sessionManagement()
				.sessionCreationPolicy(SessionCreationPolicy.NEVER)
				.and()
				.authorizeRequests()
				.anyRequest().authenticated()

				.antMatchers(HttpMethod.POST,"/ebb/").access("#oauth2.hasScope('ebb-write')")
				.antMatchers(HttpMethod.PUT,"/ebb/").access("#oauth2.hasScope('ebb-write')")
				.antMatchers(HttpMethod.DELETE,"/ebb/").access("#oauth2.hasScope('ebb-write')")
				.antMatchers(HttpMethod.POST,"/entity/product/").access("#oauth2.hasScope('admin')")
				.antMatchers(HttpMethod.PUT,"/entity/product/").access("#oauth2.hasScope('admin')")
				.antMatchers(HttpMethod.DELETE,"/entity/product/").access("#oauth2.hasScope('admin')")
				.antMatchers(HttpMethod.GET,"/entity/entityproductinfo/").access("#oauth2.hasScope('admin')")//allproductinfo
				.antMatchers(HttpMethod.GET,"/entity/allproductinfo/").access("#oauth2.hasScope('ebb-read')")
				.antMatchers("/ebb/list/").access("#oauth2.hasScope('ebb-read')")
				.antMatchers("/logistics/").access("#oauth2.hasScope('ebb-read','ebb-read')")
				.antMatchers("/logistics/").access("#oauth2.hasScope('ebb-read','ebb-read')")
				.antMatchers("/train/info/").access("#oauth2.hasScope('ebb-read','ebb-read')")
				.antMatchers("/train/member/").access("#oauth2.hasScope('ebb-read','ebb-read')");

	}

	@Bean
	public JwtAccessTokenConverter jwtAccessTokenConverter() {
		JwtAccessTokenConverter jwtAccessTokenConverter = new BaseJwtAccessTokenConverterImpl(resourceId);
		jwtAccessTokenConverter.setVerifierKey(publicKey);
		return jwtAccessTokenConverter;
	}

	@Bean
	public ResourceServerTokenServices defaultTokenServices() throws Exception {
		JwtAccessTokenConverter jwtAccessTokenConverter = jwtAccessTokenConverter();
		DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
		defaultTokenServices.setTokenStore(new JwtTokenStore(jwtAccessTokenConverter));
		defaultTokenServices.setTokenEnhancer(jwtAccessTokenConverter);
		return defaultTokenServices;
	}


	@Configuration
	@EnableGlobalMethodSecurity(prePostEnabled = true)
	public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
		@Override
		protected MethodSecurityExpressionHandler createExpressionHandler() {
			return new OAuth2MethodSecurityExpressionHandler();
		}
	}

}